package com.fand.platform.authority.service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.fand.dto.PaginationDto;
import com.fand.platform.authority.dao.NavigationDao;
import com.fand.platform.authority.dto.NavigationDto;
import com.fand.platform.authority.dto.NavigationLaDto;

/**
 * 导航服务
 * 
 * @author yaoHT
 * 
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class NavigationDefaultService implements NavigationService {
	private NavigationDao navigationDao;

	@Override
	@CacheEvict(value = NavigationService.CACHE_NAME, allEntries = true)
	public void reload() {
	}

	@Override
	@Transactional
	public NavigationDto saveNavigationByIdOrCodeForNavigation(NavigationDto saveNavigation) {
		String[] whereEqProperties;

		if (StringUtils.isNotBlank(saveNavigation.getId())) {
			whereEqProperties = new String[] { "id" };
		} else {
			whereEqProperties = new String[] { "code", "siteId", "typeId" };
		}

		NavigationDto oldNavigation = this.navigationDao.selectNavigationBy1ForMappedObject(NavigationDto.class,
				saveNavigation, null, whereEqProperties);

		if (oldNavigation == null) {
			saveNavigation.setId(UUID.randomUUID().toString());
			saveNavigation.setBeginDaTi(new Date());
			saveNavigation.setEndDaTi(new DateTime(9999, 12, 31, 0, 0, 0, 0).toDate());

			this.navigationDao.insertNavigationBy1(saveNavigation);

			return saveNavigation;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveNavigation, oldNavigation,
				"siteId", "stateId", "parentId", "typeId", "name", "orderNum", "url", "target", "dataOptions");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.navigationDao.updateNavigationBy1(saveNavigation, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveNavigation, oldNavigation, updateProperties);
		}

		return oldNavigation;
	}

	@Override
	@Transactional
	public NavigationDto saveNavigationBy2ForNavigation(NavigationDto saveNavigation) {
		NavigationDto oldNavigation = this.navigationDao.selectNavigationBy1ForMappedObject(NavigationDto.class,
				saveNavigation, new String[] {}, new String[] {});

		if (oldNavigation == null) {
			this.navigationDao.insertNavigationBy1(saveNavigation, new String[] {});

			return saveNavigation;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveNavigation, oldNavigation);

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.navigationDao.updateNavigationBy1(saveNavigation, updateProperties, new String[] {});
		}

		return saveNavigation;
	}

	@Override
	@Transactional
	public int deleteNavigationBy1(NavigationDto deleteNavigation) {
		return this.navigationDao.deleteNavigationBy1(deleteNavigation, new String[] {});
	}

	@Override
	@Transactional
	public int deleteNavigationBy2(NavigationDto deleteNavigation) {
		return this.navigationDao.deleteNavigationBy2(deleteNavigation);
	}

	@Override
	@Transactional
	public int setNavigationBy1(NavigationDto setNavigation) {
		return this.navigationDao.updateNavigationBy1(setNavigation, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setNavigationBy2(NavigationDto setNavigation) {
		return this.navigationDao.updateNavigationBy2(setNavigation);
	}

	@Override
	public Integer readNavigationBy1ForInteger(NavigationDto readNavigation) {
		return this.navigationDao.selectNavigationBy1ForObject(Integer.class, readNavigation, null, new String[] {});
	}

	@Override
	public Integer readNavigationBy2ForInteger(NavigationDto readNavigation) {
		return this.navigationDao.selectNavigationBy2ForObject(Integer.class, readNavigation, null);
	}

	@Override
	public List<Integer> readListNavigationBy1(NavigationDto readNavigation) {
		return this.navigationDao.selectNavigationBy1ForObjectList(Integer.class, readNavigation, null,
				new String[] {});
	}

	@Override
	public List<Integer> readListNavigationBy2(NavigationDto readNavigation) {
		return this.navigationDao.selectNavigationBy2ForObjectList(Integer.class, readNavigation, null);
	}

	@Override
	public NavigationDto getNavigationBy1(NavigationDto getNavigation) {
		return this.navigationDao.selectNavigationBy1ForMappedObject(NavigationDto.class, getNavigation,
				new String[] {}, new String[] {});
	}

	@Override
	public NavigationDto getNavigationBy2(NavigationDto getNavigation) {
		return this.navigationDao.selectNavigationBy2ForMappedObject(NavigationDto.class, getNavigation);
	}

	@Override
	public List<NavigationDto> findNavigationBy1(NavigationDto findNavigation) {
		return this.navigationDao.selectNavigationBy1ForMappedObjectList(NavigationDto.class, findNavigation,
				new String[] {}, new String[] {});
	}

	@Override
	public List<NavigationDto> findNavigationByTypeCo(NavigationDto findNavigation, int treeDepthNum) {
		final List<NavigationDto> navigationList = this.navigationDao.selectNavigationBy2ForMappedObjectList(
				NavigationDto.class, findNavigation);

		if (CollectionUtils.isEmpty(navigationList)) {
			return navigationList;
		}

		if (treeDepthNum > 1) {
			for (final NavigationDto itemNavigation : navigationList) {
				findNavigation.setParentId(itemNavigation.getId());

				final List<NavigationDto> childNavigationList = this.findNavigationByTypeCo(findNavigation,
						(treeDepthNum - 1));

				itemNavigation.setChilds(childNavigationList);
			}
		}

		return navigationList;
	}

	@Override
	public PaginationDto<NavigationDto> paginationNavigationBy1ForNavigationList(NavigationDto paginationNavigation) {
		return this.navigationDao.paginationNavigationBy1ForMappedObjectList(NavigationDto.class,
				paginationNavigation);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationNavigationBy1ForMapList(NavigationDto paginationNavigation) {
		return this.navigationDao.paginationNavigationBy1ForMapList(paginationNavigation);
	}

	@Override
	@Transactional
	public NavigationLaDto saveNavigationLaBy1ForNavigationLa(NavigationLaDto saveNavigationLa) {
		NavigationLaDto oldNavigationLa = this.navigationDao.selectNavigationLaBy1ForMappedObject(
				NavigationLaDto.class, saveNavigationLa, new String[] {}, new String[] {});

		if (oldNavigationLa == null) {
			this.navigationDao.insertNavigationLaBy1(saveNavigationLa, new String[] {});

			return saveNavigationLa;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveNavigationLa, oldNavigationLa);

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.navigationDao.updateNavigationLaBy1(saveNavigationLa, updateProperties, new String[] {});
		}

		return saveNavigationLa;
	}

	@Override
	@Transactional
	public NavigationLaDto saveNavigationLaBy2ForNavigationLa(NavigationLaDto saveNavigationLa) {
		NavigationLaDto oldNavigationLa = this.navigationDao.selectNavigationLaBy1ForMappedObject(
				NavigationLaDto.class, saveNavigationLa, new String[] {}, new String[] {});

		if (oldNavigationLa == null) {
			this.navigationDao.insertNavigationLaBy1(saveNavigationLa, new String[] {});

			return saveNavigationLa;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveNavigationLa, oldNavigationLa);

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.navigationDao.updateNavigationLaBy1(saveNavigationLa, updateProperties, new String[] {});
		}

		return saveNavigationLa;
	}

	@Override
	@Transactional
	public int deleteNavigationLaBy1(NavigationLaDto deleteNavigationLa) {
		return this.navigationDao.deleteNavigationLaBy1(deleteNavigationLa, new String[] {});
	}

	@Override
	@Transactional
	public int deleteNavigationLaBy2(NavigationLaDto deleteNavigationLa) {
		return this.navigationDao.deleteNavigationLaBy2(deleteNavigationLa);
	}

	@Override
	@Transactional
	public int setNavigationLaBy1(NavigationLaDto setNavigationLa) {
		return this.navigationDao.updateNavigationLaBy1(setNavigationLa, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setNavigationLaBy2(NavigationLaDto setNavigationLa) {
		return this.navigationDao.updateNavigationLaBy2(setNavigationLa);
	}

	@Override
	public Integer readNavigationLaBy1ForInteger(NavigationLaDto readNavigationLa) {
		return this.navigationDao.selectNavigationLaBy1ForObject(Integer.class, readNavigationLa, null,
				new String[] {});
	}

	@Override
	public Integer readNavigationLaBy2ForInteger(NavigationLaDto readNavigationLa) {
		return this.navigationDao.selectNavigationLaBy2ForObject(Integer.class, readNavigationLa, null);
	}

	@Override
	public List<Integer> readListNavigationLaBy1(NavigationLaDto readNavigationLa) {
		return this.navigationDao.selectNavigationLaBy1ForObjectList(Integer.class, readNavigationLa, null,
				new String[] {});
	}

	@Override
	public List<Integer> readListNavigationLaBy2(NavigationLaDto readNavigationLa) {
		return this.navigationDao.selectNavigationLaBy2ForObjectList(Integer.class, readNavigationLa, null);
	}

	@Override
	public NavigationLaDto getNavigationLaBy1(NavigationLaDto getNavigationLa) {
		return this.navigationDao.selectNavigationLaBy1ForMappedObject(NavigationLaDto.class, getNavigationLa,
				new String[] {}, new String[] {});
	}

	@Override
	public NavigationLaDto getNavigationLaBy2(NavigationLaDto getNavigationLa) {
		return this.navigationDao.selectNavigationLaBy2ForMappedObject(NavigationLaDto.class, getNavigationLa);
	}

	@Override
	public List<NavigationLaDto> findNavigationLaBy1(NavigationLaDto findNavigationLa) {
		return this.navigationDao.selectNavigationLaBy1ForMappedObjectList(NavigationLaDto.class, findNavigationLa,
				new String[] {}, new String[] {});
	}

	@Override
	public List<NavigationLaDto> findNavigationLaBy2(NavigationLaDto findNavigationLa) {
		return this.navigationDao.selectNavigationLaBy2ForMappedObjectList(NavigationLaDto.class, findNavigationLa);
	}

	@Override
	public PaginationDto<NavigationLaDto> paginationNavigationLaBy1ForNavigationLaList(
			NavigationLaDto paginationNavigationLa) {
		return this.navigationDao.paginationNavigationLaBy1ForMappedObjectList(NavigationLaDto.class,
				paginationNavigationLa);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationNavigationLaBy1ForMapList(
			NavigationLaDto paginationNavigationLa) {
		return this.navigationDao.paginationNavigationLaBy1ForMapList(paginationNavigationLa);
	}
}